import type { TColumn } from '@/components/editable-excel-table';
import type { DataIndex, TableAction, TableState } from './types';
import { calculateErrorStats } from '../utils/errorUtils';

// ------------------------------
// helpers（纯函数，便于复用与测试）
// ------------------------------
type ErrorPosition = { rowIndex: number; columnIndex: number };

/**
 * 删除行后，调整错误位置
 * @param positions 错误位置
 * @param deletedRowIndex 删除的行索引
 * @returns 新的错误位置
 */
function adjustErrorPositionsForRowDelete(positions: ErrorPosition[], deletedRowIndex: number): ErrorPosition[] {
    return positions
        .filter((pos) => pos.rowIndex !== deletedRowIndex)
        .map((pos) => (pos.rowIndex > deletedRowIndex ? { ...pos, rowIndex: pos.rowIndex - 1 } : pos));
}

/**
 * 删除行后，调整修改的单元格
 * @param modifiedCells 修改的单元格
 * @param deletedRowIndex 删除的行索引
 * @returns 新的修改的单元格
 */
function adjustModifiedCellsForRowDelete(modifiedCells: Set<string>, deletedRowIndex: number): Set<string> {
    const updated = new Set<string>();
    modifiedCells.forEach((cellKey) => {
        const [cellRowIndex, dataIndex] = cellKey.split(':');
        const cellRowIndexNum = parseInt(cellRowIndex);
        // 如果单元格的行索引不是删除的行索引，并且有数据索引，则更新修改的单元格
        if (cellRowIndexNum !== deletedRowIndex && dataIndex) {
            const newRowIndex = cellRowIndexNum > deletedRowIndex ? cellRowIndexNum - 1 : cellRowIndexNum;
            updated.add(`${newRowIndex}:${dataIndex}`);
        }
    });
    return updated;
}

/**
 * 根据激活单元格，找到下一个错误的位置
 * @param state
 * @param direction
 * @returns
 */
function findNextErrorIndexRelativeToActive<C extends TColumn>(
    state: TableState<C>,
    direction: 'next' | 'prev'
): number {
    const { errorPositions, activeCell } = state;

    console.log('findNextErrorIndexRelativeToActive', { errorPositions, activeCell, direction });

    if (!activeCell) return -1;

    const activeRow = activeCell.rowIndex;
    const activeColIndex = state.sheetData.columns.findIndex((c) => c.dataIndex === activeCell.dataIndex);

    if (direction === 'next') {
        const idx = errorPositions.findIndex(
            (pos) => pos.rowIndex > activeRow || (pos.rowIndex === activeRow && pos.columnIndex > activeColIndex)
        );
        // 不循环，找不到下一个就返回-1
        return idx;
    }

    for (let i = errorPositions.length - 1; i >= 0; i--) {
        const pos = errorPositions[i];
        if (pos.rowIndex < activeRow || (pos.rowIndex === activeRow && pos.columnIndex < activeColIndex)) {
            return i;
        }
    }
    // 不循环，找不到上一个就返回-1
    return -1;
}

/**
 * 根据错误位置，构建状态
 * @param state 当前状态
 * @param newIndex 错误位置索引
 * @returns 新的状态
 */
function buildStateForErrorIndex<C extends TColumn>(state: TableState<C>, newIndex: number): TableState<C> {
    // 如果索引无效，返回原状态
    if (newIndex < 0 || newIndex >= state.errorPositions.length) {
        return state;
    }

    const targetPosition = state.errorPositions[newIndex];
    const targetColumn = state.sheetData.columns[targetPosition.columnIndex];
    if (!targetColumn) return state;

    return {
        ...state,
        currentErrorIndex: newIndex,
        activeCell: {
            rowIndex: targetPosition.rowIndex,
            dataIndex: targetColumn.dataIndex as any,
        },
        activeRow: undefined,
    };
}

/**
 * 更新单元格值
 * @param state 当前状态
 * @param payload 更新单元格的载荷
 * @returns 更新后的状态
 */
export function updateCellValueHandler<C extends TColumn>(
    state: TableState<C>,
    payload: { rowIndex: number; dataIndex: DataIndex<C>; value: any; otherParams?: Record<string, any> }
): TableState<C> {
    const { rowIndex, dataIndex, value, otherParams = {} } = payload;
    const newData = [...state.sheetData.data];
    newData[rowIndex] = { ...newData[rowIndex], [dataIndex]: value };

    // 检查是否修改了初始值
    const initialValue = state.initialData[rowIndex]?.[dataIndex];
    const cellKey = `${rowIndex}:${dataIndex}`;
    const newModifiedCells = new Set<string>(state.modifiedCells);

    if (value !== initialValue) {
        newModifiedCells.add(cellKey);
    } else {
        newModifiedCells.delete(cellKey);
    }

    // 立即重新计算错误状态，确保错误显示和定位的及时性
    const newState = {
        ...state,
        sheetData: {
            ...state.sheetData,
            data: newData,
        },
        modifiedCells: newModifiedCells,
        ...otherParams,
    };

    // 重新计算错误统计
    const errorStats = calculateErrorStats(newData, newState.sheetData.columns, newState.initialData, newModifiedCells);

    // 更新错误位置和计数
    let newCurrentErrorIndex = -1;

    // 保持当前错误索引在有效范围内
    if (errorStats.remainingErrorPositions.length > 0) {
        // 如果当前错误索引超出范围，调整到最大有效值
        if (state.currentErrorIndex >= errorStats.remainingErrorPositions.length) {
            newCurrentErrorIndex = errorStats.remainingErrorPositions.length - 1;
        } else if (state.currentErrorIndex >= 0) {
            newCurrentErrorIndex = state.currentErrorIndex;
        } else {
            newCurrentErrorIndex = 0;
        }
    }

    // 检查当前激活的单元格是否仍然有错误，如果没有则清除激活状态
    let newActiveCell = newState.activeCell;
    if (newState.activeCell) {
        const hasError = errorStats.remainingErrorPositions.some(
            (pos) =>
                pos.rowIndex === newState.activeCell!.rowIndex &&
                newState.sheetData.columns[pos.columnIndex]?.dataIndex === newState.activeCell!.dataIndex
        );
        if (!hasError) {
            newActiveCell = undefined;
        }
    }

    return {
        ...newState,
        errorPositions: errorStats.remainingErrorPositions,
        currentErrorIndex: newCurrentErrorIndex,
        errorCount: errorStats.totalErrors,
        fixedErrorCount: errorStats.fixedErrorCount,
        activeCell: newActiveCell,
    };
}

/**
 * 创建初始状态
 * @param sheetData 表格数据
 * @returns 初始状态
 */
export function createInitialState<C extends TColumn>(sheetData?: any): TableState<C> {
    return {
        sheetData: sheetData || {
            columns: [] as unknown as C[],
            data: [],
        },
        errorCount: 0,
        activeColumn: undefined,
        activeRow: undefined,
        activeCell: undefined,
        editingCell: undefined,

        errorPositions: [],
        currentErrorIndex: -1,
        modifiedCells: new Set(),
        initialData: sheetData?.data || [],
    };
}

/**
 * 根据动作，更新状态
 * @param state
 * @param action
 * @returns
 */
export function tableReducer<C extends TColumn>(state: TableState<C>, action: TableAction<C>): TableState<C> {
    switch (action.type) {
        /**
         * 替换整表数据
         */
        case 'SET_SHEET_DATA':
            return { ...state, sheetData: action.payload };
        /**
         * 替换列定义
         */
        case 'SET_COLUMNS_WIDTH':
            const { dataIndex, width } = action.payload as { dataIndex: DataIndex<C>; width: number };
            return {
                ...state,
                sheetData: {
                    ...state.sheetData,
                    columns: state.sheetData.columns.map((c) => (c.dataIndex === dataIndex ? { ...c, width } : c)),
                },
            };
        case 'SET_DATA':
            return { ...state, sheetData: { ...state.sheetData, data: action.payload } };
        /**
         * 删除指定行
         */
        case 'DELETE_ROW': {
            const rowIndex = action.payload;
            const newData = state.sheetData.data.filter((_, index) => index !== rowIndex);

            // 重新计算序号列
            const updatedData = newData.map((row, index) => ({
                ...row,
                __index__: String(index + 1),
            }));

            // 更新错误位置与修改状态（删除行后重新计算）
            const updatedErrorPositions = adjustErrorPositionsForRowDelete(state.errorPositions, rowIndex);
            const updatedModifiedCells = adjustModifiedCellsForRowDelete(state.modifiedCells, rowIndex);

            return {
                ...state,
                sheetData: {
                    ...state.sheetData,
                    data: updatedData,
                },
                // 如果删除的是当前激活的行，清除激活状态
                activeRow: state.activeRow === rowIndex ? undefined : state.activeRow,
                activeCell: state.activeCell?.rowIndex === rowIndex ? undefined : state.activeCell,
                editingCell: state.editingCell?.rowIndex === rowIndex ? undefined : state.editingCell,
                // 更新错误相关状态
                errorPositions: updatedErrorPositions,
                currentErrorIndex: updatedErrorPositions.length > 0 ? 0 : -1,
                modifiedCells: updatedModifiedCells,
            };
        }
        /**
         * 激活单元格（用于单元格高亮、键盘导航等）
         */
        case 'SET_ACTIVE_CELL': {
            return {
                ...state,
                activeCell: action.payload,
                activeRow: undefined,
                activeColumn: undefined,
                editingCell: undefined,
            };
        }
        /**
         * 设置正在编辑的单元格（控制编辑器显隐）
         */
        case 'SET_EDITING_CELL': {
            return { ...state, editingCell: action.payload };
        }
        /**
         * 设置错误数量
         */
        case 'SET_ERROR_COUNT': {
            return {
                ...state,
                errorCount: action.payload.totalErrors,
                fixedErrorCount: action.payload.fixedErrorCount,
            };
        }
        case 'UPDATE_CELL_VALUE': {
            return updateCellValueHandler(state, action.payload);
        }
        case 'NAVIGATE_TO_ERROR': {
            const { errorPositions, currentErrorIndex, activeCell } = state;
            console.log('NAVIGATE_TO_ERROR', {
                errorPositions,
                currentErrorIndex,
                activeCell,
                payload: action.payload,
            });

            if (errorPositions.length === 0) return state;

            // 检查currentErrorIndex是否有效，如果无效则重置为-1
            let validCurrentIndex = currentErrorIndex;
            if (currentErrorIndex >= errorPositions.length || currentErrorIndex < 0) {
                validCurrentIndex = -1;
            }

            // 已有激活单元格：相对激活位置查找最近错误
            if (activeCell) {
                const newIndex = findNextErrorIndexRelativeToActive(state, action.payload);
                // 如果找不到相对位置的错误，说明已经到达边界，直接返回当前状态
                if (newIndex === -1) {
                    return state;
                }
                return buildStateForErrorIndex(state, newIndex);
            }

            // 无激活单元格：首次点击直接定位到第一个错误
            const newIndex =
                validCurrentIndex === -1
                    ? 0
                    : action.payload === 'next'
                    ? validCurrentIndex >= errorPositions.length - 1
                        ? errorPositions.length - 1 // 不循环，最多到最后一个
                        : validCurrentIndex + 1
                    : validCurrentIndex <= 0
                    ? 0 // 不循环，最少到第一个
                    : validCurrentIndex - 1;

            return buildStateForErrorIndex(state, newIndex);
        }
        case 'SET_ERROR_POSITIONS': {
            const nextState: TableState<C> = {
                ...state,
                errorPositions: action.payload,
                currentErrorIndex: action.payload.length > 0 ? 0 : -1,
            };

            // 默认激活第一个错误单元格（仅当当前没有激活单元格时）
            if (!state.activeCell && action.payload.length > 0) {
                const firstPos = action.payload[0];
                const targetColumn = state.sheetData.columns[firstPos.columnIndex];
                if (targetColumn) {
                    nextState.activeCell = {
                        rowIndex: firstPos.rowIndex,
                        dataIndex: targetColumn.dataIndex as any,
                    };
                    nextState.activeRow = undefined;
                }
            }

            return nextState;
        }
        case 'TRANSFORM_STATE': {
            // 支持函数传递，函数接收当前state并返回新的state
            // 这样可以支持链式调用和复杂的state转换逻辑
            return action.payload(state);
        }

        default:
            return state;
    }
}
